package com.sye.reflectmodule;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 反射基础语法
 */
public class BaseReflectOpr {
    /**
     * 根据字符串获取对象以及类型
     */
    @Test
    public void getObject(){
        // 通过字符串获取类名称
        /*String name = "hanrentong";
        Class c1 = name.getClass();
        System.out.println(c1.getName());//java.lang.String*/

        String name = "java.lang.String";
        Class c1 = null;
        try {
            c1 = Class.forName(name);
            System.out.println(c1.getName());//java.lang.String
            System.out.println(c1.getSuperclass());//class java.lang.Object 获取父类
        } catch (ClassNotFoundException e) {
        }
        // type属性
        Class c = Boolean.TYPE;
        Class c2 = Byte.TYPE;
        Class c3 = Float.TYPE;
        Class c4 = Double.TYPE;
    }

    /**
     * 获取类的所有构造方法
     */
    @Test
    public void getObjectDeclaredConstructors() throws ClassNotFoundException {
        Class aclass = Class.forName("com.sye.reflectmodule.javabean.Person");
        // 获取所有的构造方法
        Constructor[] declaredConstructors = aclass.getDeclaredConstructors();

        for (int i = 0; i < declaredConstructors.length; i++) {
            // 得到构造方法的类型(public的)
            System.out.print(Modifier.toString(declaredConstructors[i].getModifiers()) + "参数：");
            // 构造方法的所有参数
            Class[] parametertypes = declaredConstructors[i].getParameterTypes();
            for (int j = 0; j < parametertypes.length; j++) {
                // 构造方法的所有参数
                System.out.print(parametertypes[j].getName() + " ");
            }
            System.out.println("");
        }
        /**
         * 输出结果
         * public参数：java.lang.String java.lang.Integer
         * public参数：java.lang.Integer
         * public参数：java.lang.String
         */
    }

    /**
     * 获取类中特定的构造方法
     */
    @Test
    public void getObjectConstruct() throws Exception {
        Class aclass = Class.forName("com.sye.reflectmodule.javabean.Person");
        // 获取无参构造方法
        Constructor constructor = aclass.getDeclaredConstructor();
        System.out.println(Modifier.toString(constructor.getModifiers()));

        // 获取两个参数的构造方法
        Class[] p = {String.class,Integer.class};
        try {
            Constructor constructors = aclass.getDeclaredConstructor(p);
            System.out.print(Modifier.toString(constructors.getModifiers()) + "参数:");
            Class[] parametertypes = constructors.getParameterTypes();
            for (int j = 0; j < parametertypes.length; j++) {
                System.out.print(parametertypes[j].getName() + " ");
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    /**
     * 执行构造方法
     */
    @Test
    public void execConstruct() throws Exception {
        Class aclass = Class.forName("com.sye.reflectmodule.javabean.Person");
        Class[] p = {String.class,Integer.class};
        Constructor declaredConstructor = aclass.getDeclaredConstructor(p);
        declaredConstructor.newInstance("hanrentong",30);
        /**
         * 调用私有构造方法和上面的步骤一样
         * 只是我们要设置declaredConstructor.setAccessible(true)
         */
    }
    /**
     * 执行类的私有方法
     * 如果不是私有方法的话就去掉method.setAccessible(true);
     */
    @Test
    public void execPrivateMethod() throws Exception {
        Class aclass = Class.forName("com.sye.reflectmodule.javabean.Person");
        // titleInfo为类的方法名称 String.class为参数的类型
        Method method = aclass.getDeclaredMethod("titleInfo", String.class);
        method.setAccessible(true);
        method.invoke(aclass.newInstance(),"沃日你大爷");
    }

    /**
     * 获取类的私有字段并修改值
     */
    @Test
    public void updateClassField() throws Exception {
        Class aclass = Class.forName("com.sye.reflectmodule.javabean.Person");
        Object o = aclass.newInstance();
        Field field = aclass.getDeclaredField("name");
        field.setAccessible(true);
        field.set(o,"代码男人");
        System.out.println(o);
    }

}
